// 
// @Author: xzw
// @Description:
// @Version: 1.0.0
// @Date: 2021/3/11 上午11:18
// @Copyright: MIN-Group；国家重大科技基础设施——未来网络北大实验室；深圳市信息论与未来网络重点实验室
// 

const uti = require("../../../../crypto/utils")
const com = require("../../../../common")
const cer = require("../../../../crypto/cert/cert")
const identity = require('../../../identity')

// 
// 设置默认identity
// @param name string, tx *sql.Tx
// 
// @returns (bool, error)
// 
function setDefaultIdentityFromStorage(name, tx) {
    var stmt,info
    try{
        stmt = tx.prepare("update identityinfo set is_default = 1 where name= ?")
        info = stmt.run(name)
    }catch(err){
        return [false, err]
    }

    console.log("设置默认身份：", info)

    return [true, null]
}

// 
// 取消默认identity
// @param name string, tx *sql.Tx
// @returns (bool, error)
// 
function cancelDefaultIdentityFromStorage(name, tx) {
    var stmt,info
    try{
        stmt = tx.prepare("update identityinfo set is_default= 0 where name= ?")
        info = stmt.run(name)
    }catch(err){
        return [false, err]
    }
    console.log("取消默认身份设置：", info)

    return [true, null]
}

// 
// 获取默认identity
// @param row *sql.Row
// @returns (*identity.Identity, error)
// 
function getDefaultIdentityFromStorage(row) {
    if(row === null || row === undefined){
        return [null, null]
    }
    var pubStr 
    var priStr 
    var algo  
    var sign 
    var pass 
    var certStr
    var name 
    var def 
    var prikeyRawByte
    var pubByte 
    try{
        pubStr = row.pubkey
        priStr = row.prikey
        algo = row.pubkey_algo
        sign = row.signature_algo
        pass = row.pass
        certStr = row.cert
        name = row.name
        def = row.is_default
        prikeyRawByte = row.prikey_raw_byte
        pubByte = uti.Str2Bytes(pubStr)
    }catch(err){
        return [null, err]
    }


    var pubByte = uti.Str2Bytes(new Buffer.from(pubStr, 'base64').toString("hex"))
    var pubKey = uti.UnMarshalPublicKey(pubByte, algo)
    if (pubKey[1] != null) {
        return [null, pubKey[1]]
    }

    var priByte = uti.Str2Bytes(new Buffer.from(priStr, 'base64').toString("hex"))
    var priKey = uti.UnMarshalPrivateKey(priByte, algo)
    if (priKey[1] != null) {
        return [null, priKey[1]]
    }

    var cert = new cer.Certificate

    certStr = new Buffer.from(certStr, 'base64').toString();
    console.log("certStr is", certStr)
    err = cert.FromPem(certStr, null, com.SymmetricAlgorithm.SM4ECB)
    if (err != null) {
        return [null, err]
    }

    priKeyByte = uti.Str2Bytes(prikeyRawByte)


    var id = new identity.Identity(name, new identity.KeyParam(algo, sign), priKey[0], priKeyByte, pubKey[0], pass, cert)

    return [id, null]

}

// 
// 根据名字查询identity
// @param name string, db *sql.DB
// @returns (*identity.Identity, error)
// 
function getIdentityByNameFromStorage(name, db) {
    var stmt = db.prepare('SELECT * from identityinfo where name = ?')
    var rows = stmt.get(name)

    return getIdentityFromSqlRows(rows)
}

// 
// 查询所有identity
// @param (row *sql.Rows)
// @returns (*identity.Identity, error)
// 
function getIdentityFromSqlRows(row) {
    if (row === undefined){
        return [null, null]
    }
    var pubStr 
    var priStr 
    var algo  
    var sign 
    var pass 
    var certStr
    var name 
    var def 
    var prikeyRawByte
    var pubByte 
    try{
        pubStr = row.pubkey
        priStr = row.prikey
        algo = row.pubkey_algo
        sign = row.signature_algo
        pass = row.pass
        certStr = row.cert
        name = row.name
        def = row.is_default
        prikeyRawByte = row.prikey_raw_byte
        pubByte = uti.Str2Bytes(pubStr)
    }catch(err){
        return [null, err]
    }

    console.log("pubStr 啥类型", pubStr)
    var pubByte = uti.Str2Bytes(new Buffer.from(pubStr, 'base64').toString("hex"))
    console.log("pubBytes is ", pubByte)

    var pubKey = uti.UnMarshalPublicKey(pubByte, algo)
    if (pubKey[1] != null) {
        return [null, pubKey[1]]
    }

    var priByte = uti.Str2Bytes(new Buffer.from(priStr, 'base64').toString("hex"))
    

    var priKey = uti.UnMarshalPrivateKey(priByte, algo)
    if (priKey[1] != null) {
        return [null, priKey[1]]
    }

    var cert = new cer.Certificate

    certStr = new Buffer.from(certStr, 'base64').toString();
    console.log("certStr is", certStr)
    err = cert.FromPem(certStr, null, com.SymmetricAlgorithm.SM4ECB)
    if (err != null) {
        return [null, err]
    }

    priKeyByte = uti.Str2Bytes(prikeyRawByte)


    var id = new identity.Identity(name, new identity.KeyParam(algo, sign), priKey[0], priKeyByte, pubKey[0], pass, cert)

    return [id, null]
}

//
// 查询所有identity
// @param (row *sql.Rows)
// @returns (*identity.Identity, error)
//
function getIdentityFromSqlRow(row) {
    if (row === undefined){
        return [null, null]
    }
    var pubStr 
    var priStr 
    var algo  
    var sign 
    var pass 
    var certStr
    var name 
    var def 
    var prikeyRawByte
    var pubByte 
    try{
        pubStr = row.pubkey
        priStr = row.prikey
        algo = row.pubkey_algo
        sign = row.signature_algo
        pass = row.pass
        certStr = row.cert
        name = row.name
        def = row.is_default
        prikeyRawByte = row.prikey_raw_byte
        pubByte = uti.Str2Bytes(pubStr)
    }catch(err){
        return [null, err]
    }

    console.log("pubStr 啥类型", pubStr)
    var pubByte = uti.Str2Bytes(new Buffer.from(pubStr, 'base64').toString("hex"))
    console.log("pubBytes is ", pubByte)

    var pubKey = uti.UnMarshalPublicKey(pubByte, algo)
    if (pubKey[1] != null) {
        return [null, pubKey[1]]
    }

    var priByte = uti.Str2Bytes(new Buffer.from(priStr, 'base64').toString("hex"))
    

    var priKey = uti.UnMarshalPrivateKey(priByte, algo)
    if (priKey[1] != null) {
        return [null, priKey[1]]
    }

    var cert = new cer.Certificate

    certStr = new Buffer.from(certStr, 'base64').toString();
    console.log("certStr is", certStr)
    err = cert.FromPem(certStr, null, com.SymmetricAlgorithm.SM4ECB)
    if (err != null) {
        return [null, err]
    }

    priKeyByte = uti.Str2Bytes(prikeyRawByte)


    var id = new identity.Identity(name, new identity.KeyParam(algo, sign), priKey[0], priKeyByte, pubKey[0], pass, cert)

    return [id, null]
}

module.exports = {
    getIdentityByNameFromStorage: getIdentityByNameFromStorage,
    getIdentityFromSqlRows: getIdentityFromSqlRows,
    getDefaultIdentityFromStorage: getDefaultIdentityFromStorage,
    cancelDefaultIdentityFromStorage: cancelDefaultIdentityFromStorage,
    setDefaultIdentityFromStorage:setDefaultIdentityFromStorage,
    getIdentityFromSqlRow: getIdentityFromSqlRow
}
